package com.hoopchina.util.download;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.hoopchina.service.NewsService;
import com.hoopchina.util.ImageDispose;
import com.hoopchina.util.NetUtil;
import com.hoopchina.util.UrlUtils;

import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class Downloader {

    protected static final String                    TAG                    = "Downloader";
    private static final int                         SAVEPATH_NOT_AVAILABLE = -1;
    private static final int                         FILE_EXISTS            = -2;
    private static final int                         DOWNLOAD_COMPLETE      = 0;
    static Downloader                                instance               = null;
    private String                                   mFileName              = "";
    private static final String RSS_LOG="RSS_LOG";
    private HashMap<String, SoftReference<Drawable>> drawableCache;

    private Downloader() {
        drawableCache = new HashMap<String, SoftReference<Drawable>>();
    }

    public static Downloader getInstance() {
        if ( instance == null )
            instance = new Downloader();
        return instance;
    }

    public int download( final String aUrl, String aSavePath, final DownloadCallback callback ) {

        // setFileName( aUrl.substring( aUrl.lastIndexOf( "/" ) + 1 ) );
        setFileName( UrlUtils.getNameFromUrl( aUrl ) );
        Log.d( TAG, "fileName = " + getFileName() );
        try {
            File savePath = new File( aSavePath );
            if ( checkStorable( savePath ) == false ) {
                // TODO: throws new exception?
                return SAVEPATH_NOT_AVAILABLE;
            }
        }
        catch ( Exception e ) {
            // TODO: handle exception
        }

        final File saveFile = new File( aSavePath, getFileName() );
        if ( saveFile.exists() ) {
            Log.i( TAG, "FILE_EXISTS" );
            saveFile.delete();
            // return FILE_EXISTS;
        }
        final File tmpFile = new File( aSavePath, getFileName()+".tmp" );

        NewsService.getTheadPool(true).submit( new Runnable() {

            @Override
            public void run() {

                try {
                    URL reqUrl = new URL( aUrl );
                    HttpURLConnection conn = ( HttpURLConnection ) reqUrl.openConnection();
                    conn.setConnectTimeout( 5 * 1000 );
                    conn.setRequestMethod( "GET" );
                    conn.setRequestProperty( "Accept", "*/*" );
                    conn.setRequestProperty( "Accept-Language", "zh-CN" );
                    conn.setRequestProperty( "Charset", "UTF-8" );
                    conn.connect();

                    if ( conn.getResponseCode() == 200 ) {
                        Log.i( TAG, "200 OK,realUrl: " + conn.getURL().toString() );
                        InputStream is = conn.getInputStream();
                        int length = conn.getContentLength();
                        Log.i( TAG, "文件:" + getFileName() + ",服务器端大小: " + length );
                        if ( length != -1 ) {
//                            byte[] imgData = new byte[length];
//                            byte[] temp = new byte[512];
//                            int readLen = 0;
//                            int destPos = 0;
//                            while ( ( readLen = is.read( temp ) ) > 0 ) {
//                                System.arraycopy( temp, 0, imgData, destPos, readLen );
//                                destPos += readLen;
//                            }
//                            RandomAccessFile finalFile = new RandomAccessFile( tmpFile, "rwd" );
//                            finalFile.write( imgData );
//                            finalFile.close();
                            
                            // temp fix
                            OutputStream out = new FileOutputStream( tmpFile );
                            byte buf[] = new byte[1024];
                            int len;
                            while ( ( len = is.read( buf ) ) > 0 )
                                out.write( buf, 0, len );
                            out.close();
                            // temp fix end
                            tmpFile.renameTo( saveFile );
                            Log.i( TAG, "文件:" + getFileName() + ",下载完成,重命名 为: " + saveFile );
                            is.close();

                            if ( callback != null ) {
                                DownloadTask task = new DownloadTask( aUrl, null );
                                callback.onFinished( task );
                            }
                        }
                        else {
                            Log.i( TAG, "Unkown file size" );
                            throw new IOException( "Unkown file size " );
                        }
                    }
                    else {
                        Log.i( TAG, "can't connect to server" );
                        throw new IOException( "can't connect to server " );
                    }

                }
                catch ( MalformedURLException e ) {
                    // caused by new URL( aUrl );
                    Log.e( TAG, "MalformedURLException :" + e.toString() );
                }
                catch ( IOException e ) {
                    // caused by reqUrl.openConnection();
                    Log.e( TAG, "IOException :" + e.toString() );
                }

            }
        } );
        return DOWNLOAD_COMPLETE;
    }

    /**
     * 检查路径是否可用
     */
    public static boolean checkStorable( File aSavePath ) {
        boolean res = false;
        if ( aSavePath.toString().contains( "sdcard" )
                && !Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED ) ) {
            res = false;
        }
        else {
            if ( !aSavePath.exists() )
                res = aSavePath.mkdirs();
            else
                res = true;
        }
        return res;
    }

    public void setFileName( String aFileName ) {
        this.mFileName = aFileName;
    }

    public String getFileName() {
        return mFileName;
    }

    public interface DrawableDownloadCallback {
        public void drawableDownloaded( Drawable imageDrawable, Object tag );
    }

    private static Boolean   IMG_BAIDU  = false;
    private static final int OK         = 200;
    private static final int ONE_SECOND = 1000;
    private static final int MAX_LENGTH = 512;

    public Drawable DownloadDrawable( final String aSavePath,final String aUrlString, Context context,
           final int picWidthPX, final Downloader.DrawableDownloadCallback drawableDownloadCallback ) {
    	if(aUrlString.trim().equalsIgnoreCase( "" )||aUrlString.equalsIgnoreCase( "" )){
    		 Log.d(RSS_LOG, "num3=DownloadDrawable===========the url is null");
    		 return null;
    	}
           
       /* if(aUrlString.equalsIgnoreCase( "" ))
            return null;*/
        
        final String aUniqueFileName = UrlUtils.getNameFromUrl( aUrlString );

        if ( drawableCache.containsKey( aUniqueFileName ) ) {
        	//如果该图片已存在则返回
            SoftReference<Drawable> softReference = drawableCache.get( aUniqueFileName );
            Drawable drawable = softReference.get();
            if ( drawable != null ) {
            	Log.d(RSS_LOG, "num4=DownloadDrawable===========the drawable is inner");
                return drawable;
            }
        }
        File saveDirectory = new File( aSavePath );
        if ( !saveDirectory.exists() ) {
            saveDirectory.mkdirs();
        }

        final File saveFile = UrlUtils.getFileFromUrl( aSavePath, aUrlString );
        
        if ( saveFile.exists() ) {
            Drawable drawable = BitmapDrawable.createFromPath( saveFile.getPath() );
            drawableCache.put( aUniqueFileName, new SoftReference<Drawable>( drawable ) );

            return drawable;

        }
        //
        if (NetUtil.checkNet(context)) {
        	 final Handler handler = new Handler() {
                 public void handleMessage( Message message ) {
                     drawableDownloadCallback.drawableDownloaded( ( Drawable ) message.obj,
                             aUniqueFileName );
                 }
             };
             
             NewsService.getTheadPool(false).submit( new Runnable() {

                 public void run() {
                     Drawable drawable = loadDrawableFromUrl( aSavePath, aUrlString, aUniqueFileName ,picWidthPX);
                     if (drawable!=null) {
                    	 drawableCache.put( aUniqueFileName, new SoftReference<Drawable>( drawable ) );
                     }
                         Message message = handler.obtainMessage( 0, drawable );
                         handler.sendMessage( message );
                         Log.d(RSS_LOG, "num6=DownloadDrawable===========load from net");
                     
                 }
             } );
		}
		return null;
    }

    private static Drawable loadDrawableFromUrl( String aSavePath, String aUrlString,
            String aUniqueFileName ,int picWidthPX) {
        Drawable d = null;
        File saveDirectory = new File( aSavePath );
        if ( saveDirectory.exists() ){
        	File[] del = saveDirectory.listFiles();
			int len=del.length;
			if (len>50) {
				for (int i = len-1; i >=0; i--) {
					del[i].delete();
				}
			}
        }else {
        	saveDirectory.mkdirs();
		}
        

        final File saveFile = new File( aSavePath, aUniqueFileName );
        final File tmpFile = new File( aSavePath, aUniqueFileName + ".tmp" );

        if ( !saveFile.exists() && !tmpFile.exists() ) {
            try {
                if ( aUrlString.contains( ".baidu.com" ) ) {
                    IMG_BAIDU = true;
                }

                URL reqUrl = new URL( aUrlString );
                HttpURLConnection conn = ( HttpURLConnection ) reqUrl.openConnection();
                conn.setConnectTimeout( 5 * ONE_SECOND );
                conn.setRequestMethod( "GET" );
                conn.setRequestProperty( "Accept", "*/*" );
                conn.setRequestProperty( "Accept-Language", "zh-CN" );
                conn.setRequestProperty( "Charset", "UTF-8" );
            //    if ( IMG_BAIDU ) {
                  //  conn.setRequestProperty( "Referer", "http://db-testing-img15.db01.baidu.com:8890" );
             //   }
                conn.connect();
                if ( conn.getResponseCode() == OK ) {
                    InputStream is = conn.getInputStream();
                    int length = ( int ) conn.getContentLength();

                    if ( length != -1 ) {
                        byte[] imgData = new byte[length];
                        byte[] temp = new byte[MAX_LENGTH];
                        int readLen = 0;
                        int destPos = 0;
                        while ( ( readLen = is.read( temp ) ) > 0 ) {
                            System.arraycopy( temp, 0, imgData, destPos, readLen );
                            destPos += readLen;
                        }
                        RandomAccessFile finalFile = new RandomAccessFile( tmpFile, "rwd" );
                        //如果图像过大，则进行压缩
                        byte[] reSize=null;
                       /* if (picWidthPX!=0) {
                        	reSize=ImageDispose.changeBigPicSize(imgData, picWidthPX);
                        	if (reSize!=null&&reSize.length>0) {
								imgData=reSize;
							}
						}*/
                        finalFile.write( imgData );
                        
                        imgData = null;
                        temp = null;
                        reSize=null;
                        finalFile.close();
                        tmpFile.renameTo( saveFile );
                        String path = saveFile.getPath();
                        d = Drawable.createFromPath( path );
                        is.close();
                    }
                    else {
                    	d=null;
                        throw new IOException( "Unkown file size " );
                    }

                }
                else {
                	d=null;
                    throw new IOException( "can't connect to server " );
                }

            }
            catch ( IOException e ) {
            	d=null;
                e.printStackTrace();
                tmpFile.delete();
                saveFile.delete();
            }
        }// end if
        else {
            if ( saveFile.exists() ) {
                d = BitmapDrawable.createFromPath( saveFile.getPath() );
            }
            else {
                d = null;
            }

        }
        return d;
    }
}